/*
 * @Descripttion: 链表
 * @Author: liuWei37853264@qq.com
 * @Date: 2021-07-19 17:29:53
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2021-07-24 20:51:39
 */
class Node {
  public ele: any;
  public next: any;
  constructor(ele: any) {
    // 保存元素
    this.ele = ele;
    this.next = null;
  }
}
interface LinkedListType {
  append?: (index: any) => void;
  insert?: (position: number, ele: any) => void;
  get?: (index: number) => any;
  indexOf?: (ele: any) => number;
  update?: (position: number, ele: any) => void;
}
class LinkedList implements LinkedListType {
  public length: number;
  public head: any;
  constructor() {
    this.head = null;
    this.length = 0;
  }

  /**
   * 链表里添加元素
   * @param ele
   */
  append(ele: any): void {
    const newNode = new Node(ele);
    // 当前节点为null的时候new一个node
    if (this.head === null) {
      this.head = newNode;
    } else {
      // head不为null表示该链表长度不为1
      let cur = this.head;
      while (cur.next) {
        cur = cur.next;
      }
      cur.next = newNode;
    }
    this.length++;
  }

  /**
   * 插入元素
   * @param position 位置
   * @param ele 元素
   * @returns
   */
  insert(position: number, ele: any): void {
    // 越界判断
    if (position > this.length || position < 0) return;
    const newNode: any = new Node(ele);
    // ==0表示在头部添加
    if (position === 0) {
      // 将头部的next指向当前的链表
      newNode.next = this.head;
      this.head = newNode;
    } else {
      let i: number = 0;
      let cur: any = this.head;
      // 链表前节点
      let pre = null;
      while (i++ < position) {
        pre = cur;
        // 链表的next
        cur = cur.next;
      }
      pre.next = newNode;
      newNode.next = cur;
    }
    this.length++;
  }

  /**
   *
   * @param index 位置
   */
  get(index: number): any {
    if (index > this.length - 1 || index < 0) return;
    else {
      let i = 0;
      let cur = this.head;
      while (i++ < index) {
        cur = cur.next;
      }
      return cur;
    }
  }

  /**
   *
   * @param ele
   * @returns 索引
   */
  indexOf(ele: any): number {
    if (this.isEmpty()) return -1;
    let i = 0;
    let cur = this.head;
    while (cur) {
      if (cur.ele === ele) break;
      cur = cur.next;
      i++;
    }
    return cur === null ? -1 : i;
  }

  /**
   * 更新某个位置链表的ele
   * @param position
   * @param ele
   */
  update(position: number, ele: any): void {
    /**
     * 方法1
     */
    this.removeAt(position);
    this.insert(position, ele);
  }

  /**
   * 根据位置移除
   * @param position
   */
  removeAt(position: number): void {
    const length = this.length;
    let cur = this.head;
    if (position > length || position < 0) return;
    // 如果总长度为1且需要移除则head赋值为null
    else if (this.length === 1) {
      this.head = null;
    } else {
      // 需要remove头的时候 讲head的指针指向head的next
      if (position === 0) {
        if (cur && cur.next) {
          this.head = cur.next;
        }
      } else {
        let i = 0;
        let pre = null;
        while (i++ < position) {
          pre = cur;
          cur = cur.next;
        }
        pre.next = cur?.next;
      }
    }
    this.length--;
    return cur.ele;
  }

  /**
   * 移除元素
   * @param ele
   */
  remove(ele: any): void {
    this.removeAt(this.indexOf(ele));
  }

  /**
   * 是否空链表
   * @returns
   */
  isEmpty(): boolean {
    return this.head === null;
  }

  /**
   * 链表的size
   * @returns
   */
  size(): number {
    return this.length;
  }
}

export { LinkedList, Node };
